package com.hundsun.epay.autosimu.internal.rules;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import com.hundsun.epay.autosimu.utils.StringUtility;

/**
 * 字段控制规则
 * @author Clown
 *
 */
public class FieldControlRules extends Rules {
	protected boolean intercept = false;   //截取
	protected int offset;    //下表偏移
	protected int length;    //长度
	protected Map<String, FieldControlMap> controlMap;    //控制映射
	protected boolean defineOvertime;
	protected boolean defineException;
	protected String overtimeReq;
	protected String exceptionReq;
	
	private FieldControlRules() {
		super();
		controlMap = new HashMap<String, FieldControlMap>();
	}
	
	public FieldControlRules(String rules) {
		this();
		int indexLeft = rules.indexOf("{");
		if(indexLeft >= 0) {
			String controlRules = rules.substring(indexLeft);
			parseRules(rules.substring(0, indexLeft));    //解析key
			parseFieldControlRule(controlRules);    //解析控制规则
		}else {
			parseRules(rules);    //解析key
		}
	}
	
	public static void main(String[] args) {
		System.out.println("dadasd".substring(0, -1));
	}

	protected void parseFieldControlRule(String rules){
		if(!(rules.startsWith("{") && rules.endsWith("}"))){
			throw new RuntimeException("Invalid control rule defination.");
		}
		//截去第一个和最后一个
		rules = rules.substring(1, rules.length() - 1);
		//查找第一个 冒号
		int firstColon = rules.indexOf(":");
		if(firstColon == rules.length() - 1){
			throw new RuntimeException("Invalid location of control-mapping's flag");
		}
		//冒号前为规则：\d+(,\d+)?    冒号后：req=resp,req=resp
		String interceptDefination = rules;
		String controlMapDefination = null;
		if(firstColon >= 0){   //发现控制映射规则起始标志
			interceptDefination = rules.substring(0, firstColon);
			controlMapDefination = rules.substring(firstColon + 1);
		}
		//解析字段截取规则
		parseIntercepte(interceptDefination);
		//解析字段控制映射
		parseControlMap(controlMapDefination);
	}
	
	/**
	 * 解析字段截取规则
	 * @param rules
	 */
	protected void parseIntercepte(String rules){
		if(StringUtility.isBlank(rules)){
			this.intercept = false;
		}
		boolean checkIntercept = Pattern.matches("\\-?\\d+(,\\d+)?", rules);
		if(checkIntercept){
			this.intercept = true;
			int indexComma = rules.indexOf(",");
			this.offset = Integer.parseInt(rules.substring(0, indexComma < 0 ? rules.length() : indexComma));
			this.length = indexComma < 0 ? 1 : Integer.parseInt(rules.substring(indexComma + 1, rules.length()));
			if(this.length <= 0){
				throw new RuntimeException("Invalid intercept length.");
			}
		}else{
			throw new RuntimeException("Invalid interception defination.");
		}
	}
	
	/**
	 * 解析控制映射规则
	 * @param rules
	 */
	protected void parseControlMap(String rules){
		if(StringUtility.isBlank(rules)){
			return;
		}
		String[] contorlMappingDefs = rules.split(",");
		for (String mapDefination : contorlMappingDefs) {
			int indexEqual = mapDefination.indexOf("=");
			if(indexEqual <= 0 ){
				throw new RuntimeException("Invalid control mapping defination");
			}
			String req = mapDefination.substring(0, indexEqual);
			String resp = mapDefination.substring(indexEqual + 1);
			FieldControlMap controlResp = new FieldControlMap(resp);
			String controlReq = req;
			if("".equals(req)) {
				controlReq = DEFAULT_MAPPING_KEY;
			}
			//字段控制规则记录超时，异常等的控制情况
			if(controlResp.isOvertime()) {
				this.defineOvertime = true;
				this.overtimeReq = controlReq;
			}else if(controlResp.isException()) {
				this.defineException = true;
				this.exceptionReq = controlReq;
			}else {
				this.controlMap.put(controlReq, controlResp);
			}
		}
	}
	
	@Override
	protected Rules getParentInstance() {
		throw new UnsupportedOperationException();    //字段控制内部关键字名称不支持父子关系
	}

	/**
	 * @return the intercept
	 */
	public boolean isIntercept() {
		return intercept;
	}

	/**
	 * @return the offset
	 */
	public int getOffset() {
		return offset;
	}

	/**
	 * @return the length
	 */
	public int getLength() {
		return length;
	}

	/**
	 * @return the controlMap
	 */
	public Map<String, FieldControlMap> getControlMap() {
		return controlMap;
	}

	public boolean isDefineOvertime() {
		return defineOvertime;
	}

	public boolean isDefineException() {
		return defineException;
	}

	public String getOvertimeReq() {
		return overtimeReq;
	}

	public String getExceptionReq() {
		return exceptionReq;
	}
}
